from flask import request, render_template
from flask_login import current_user
from flask import Blueprint, redirect, url_for
from flask_login import login_required, login_user, logout_user

from functools import wraps
from utils import db, generate_id, get_param
from models import Topic, Tag, TopicWithTag
import sqlalchemy
from werkzeug.routing import BaseConverter
from exceptions import ParamException, UniqueException

from utils import login_manager

main = Blueprint('main', __name__)

from flask.views import View
from models import User



class TemplateView(View):
    template_name = None
    methods = ['GET', 'POST']

    def dispatch_request(self, *args, **kwargs):
        if request.method == 'GET':
            return self.get(*args, **kwargs)
        elif request.method == 'POST':
            return redirect(self.post(*args, **kwargs))

    def get_context_data(self):
        context = {}
        return context

    def get(self, *args, **kwargs):
        context = self.get_context_data()
        return render_template(self.template_name, **context)

    def post(self, *args, **kwargs):
        return url_for('main.index')


class ActionView(View):
    methods = ['GET', 'POST']

    def dispatch_request(self, *args, **kwargs):
        return getattr(self, request.method.lower())(*args, **kwargs)


class IndexView(TemplateView):
    template_name = 'index.html'

    def get_context_data(self):
        context = super().get_context_data()
        
        context['current_tag_name'] = get_param('tag', 'string', required=False,
            default=None, max_length=48, min_length=1)
        context['tags'] = Tag.all()

        return context


class LoginView(TemplateView):
    template_name = 'login.html'

    def post(self):
        username = get_param('username', 'string', required=True,
            max_length=64, min_length=1)
        password = get_param('password', 'string', required=True,
            max_length=64, min_length=1)
        user = User.query.filter_by(username=username, password=password).first()
        if user:
            login_user(user, remember=True)        
        else:
            return url_for('main.login')
        next_url = request.args.get('next')
        return next_url or url_for('main.index')


class TopicView(TemplateView):
    template_name = 'topic/index.html'

    def get_context_data(self):
        context = super().get_context_data()

        return context


class TopicCreateView(TemplateView):
    template_name = 'topic/create.html'
    decorators = [login_required, ]

    def get_context_data(self):
        context = super().get_context_data()
        context['tags'] = Tag.all()
        return context


class SettingView(TemplateView):
    template_name = 'setting.html'
    decorators = [login_required, ]

    def get_context_data(self):
        context = super().get_context_data()
        if current_user.is_admin:
            context['tags'] = Tag.all()
        return context


class LogoutView(ActionView):
    decorators = [login_required, ]

    def get(self, *args, **kwargs):
        logout_user()
        next_url = get_param('next', 'string', default='/')
        return redirect(next_url)


class TagView(ActionView):
    decorators = [login_required, ]

    def post(self, *args, **kwargs):
        name = get_param('name', 'string', required=True)
        display_name = get_param('display_name', 'string', required=True)
        Tag.create(name, display_name)
        return redirect(url_for('main.setting'))

def register():
    main.add_url_rule('/', view_func=IndexView.as_view('index'))
    main.add_url_rule('/login', view_func=LoginView.as_view('login'))
    main.add_url_rule('/logout', view_func=LogoutView.as_view('logout'))
    main.add_url_rule('/topic/<regex(r"[a-z0-9-]{36}"):id>', view_func=TopicView.as_view('topic'))
    main.add_url_rule('/topic/create', view_func=TopicCreateView.as_view('topic_create'))
    main.add_url_rule('/setting', view_func=SettingView.as_view('setting'))
    main.add_url_rule('/tag', view_func=TagView.as_view('tag'))

"""
# 网站首页
@main.route('/', methods=['GET', ])
@login_required
def index_page():
    data = {}
    data['current_tag_name'] = get_param('tag', 'string', required=False,
        default=None, max_length=48, min_length=1)
    print(data)
    data['tags'] = Tag.all()
    return render_template('index.html', **data)


@main.route('/login', methods=['GET', ])
def login_get():
    return render_template('login.html')

@main.route('/login', methods=['POST', ])
def login_post():
    return render_template('login.html')

# 列出Tag
@main.route('/tags', methods=['GET', ])
def list_tags():
    tags = db.session.query(Tag).all()
    return tags


# 新建Tag
@main.route('/tags', methods=['POST', ])
def save_tags():
    name = get_param('name', 'string', max_length=48, min_length=1)
    display_name = get_param('display_name', 'string', max_length=64, min_length=1)
    try:
        tag = Tag(
            id=generate_id(),
            name=name,
            display_name=display_name
        )
        db.session.add(tag)
        db.session.commit()
    except sqlalchemy.exc.IntegrityError as e:
        raise UniqueException('{0} already exists'.format(name))
    return tag


# 主题首页
@main.route('/topics', methods=['GET', ])
def list_topics():
    tag = get_param('tag', 'string', required=False, default='all')
    if tag == 'all':
        topics = db.session.query(Topic).all()
    else:
        tag_id = db.session.query(Tag).filter_by(Tag.name == tag).first().id
        topics = db.session.query(TopicWithTag).filter_by(TopicWithTag.tag_id == tag_id).all()
    return topics


# 新建主题
@main.route('/topics', methods=['POST', ])
def save_topic():
    db.session.add(Topic(
        id=generate_id(),
        title='ssss',
        content='ssssssssssssssss'
    ))
    db.session.commit()
    return 'save_topic'


@main.route('/topic/<uuid:id>', methods=['GET', ])
def show_topic(id):
    id = str(id)
    topic = Topic.query.filter(Topic.id==id).first()
    return jsonify(topic)


# 编辑主题
@main.route('/topics/update', methods=['POST'])
def update_topic():
    return 'update_topics'



class TopicsView(BaseView):
    def get(self):
        # 主题首页
        return {'ss': 'sss'}
    
    def post(self):
        # 新建主题
        Topic(
            id=utils.generate_id(),

        )
        return {'sss': 'eee'}


class TopicsUpdateView(BaseView):
    def post(self):
        # 编辑主题
        return {'ss': 'ss'}


app.add_url_rule('/topics', view_func=TopicsView.as_view('topics_view'))
app.add_url_rule('/topics/update', view_func=TopicsUpdateView.as_view('topics_update_view'))

"""
